using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;

using Kypris2.CoreElements;
using Jamila2.CoreElements;
using Jamila2.Tools;

namespace GonzalesCore.CoreElements
{
    public enum CategoryOfClaim { General = 0, Entertainment = 1, PACEMarketingEvent = 2 }; // Thang Nguyen added PACEMarketingEvent 27/03/2013
    public enum TypeOfClaimDetail { Cash=0, CreditCard };    

    public class GonzalesClaimHeader : Kypris2.CoreElements.ClaimHeader, IElement
    {
        public enum TypeOfClaimStatus { Null, New, Draft, Submitted, Escalated, Approved, Authorized, PendingForFinanceVerification, SubmittedForPayment, PendingForAuthorize, PendingForPayment, RejectedByApprover, RejectedByAuthorizer, Verified, Processed, RejectedByFinance, FinanceApproval, RejectedByFinanceApprover, RejectedByFinanceApproverToFA, OnHold, Paid, Cancelled, ProcessedUpdated }

        public DateTime PaidOn = DateTime.MinValue;
        public DateTime AuthorizedOn = DateTime.MinValue;
        public DateTime FinanceApprovedOn = DateTime.MinValue;
        public DateTime OnHoldOn = DateTime.MinValue;

        public SystemUser AuthorizedBy = null;
        public SystemUser FinanceApprovedBy = null;
        public SystemUser OnHoldBy = null;
        public SystemUser NextAuthorizer = null;
        public SystemUser NextFinanceAdmin = null;
        public SystemUser NextFinanceApprover = null;     
        //added by agnes[31march2009] - for enhancement
        public string NextApproverEmail = null;

        public string ExtraProperties = "";
        public new GonzalesClaimHeader.TypeOfClaimStatus Status = GonzalesClaimHeader.TypeOfClaimStatus.New;
        public Currency LocalCurrency = null;
        public CategoryOfClaim Category = CategoryOfClaim.General;

        public decimal TotalLocalAmountAlreadyPaid = 0;
        public decimal TotalLocalActualAmountLeft = 0;
        public decimal AdvanceLessPay = 0;

        public string DefaultCountryCode = "";
        public string DefaultCurrencyCode = "";
        public decimal DefaultExchangeRate = 0;
        // Thang Nguyen added 25/03/2013
        public string DefaultProjectID = string.Empty;

        // Cheque 
        public string ChequeNo = "";
        public string ChequeIssuesBank = "";

        public GonzalesClaimHeader()
            : base()
        {
            this.internal_id = SwissArmy.UniqueID();
        }

        public GonzalesClaimHeader(string InternalID, string Reasons)
            : base(InternalID, Reasons)
        {
            
        }
    }

    public class GonzalesClaimItem : ClaimItem, IElement
    {
        public DateTime DateEnd = DateTime.MinValue;        
        public string ProjectID = "";
        public string ChargeToProfitCenter = "";
        public string ChargeToEmployeeiD = "";
        public Country Country = null;
        public string City = "";
        public decimal Tax = 0;
        public decimal DailyRate = 0; // only use during expand breakdown
        public TypeOfClaimDetail ClaimDetailType = TypeOfClaimDetail.Cash;
        public string Remarks = "";

        public bool HavingReceipts = false;
        public bool HavingPopOut = false;
        public bool IsPersonnal
        {
            get
            {
                if (this.ClaimType != null)
                {
                    return (this.ClaimType.InternalID.CompareTo("XXX") == 0);
                }
                else
                {
                    return false;
                }
            }
        }
        
        public bool IsNew = false; // not in database, just an indicator for new unexpected claim item
        public bool MarkForDelete = false; // not in database, just an indicator for mark for delete
        public decimal ActualExchangeRate = 1; // not in database, calculate again the actual rate table during runtime

        public string ParentIDInFI = "";
        public string ParentID = "";

        public string AuthorizerRemarks = "";
        public bool AuthorizerState = false;

        public string FinanceApproverRemarks = "";
        public bool FinanceApproverState = false;

        public GonzalesClaimItem()
            : base()
        {
            this.internal_id = SwissArmy.UniqueID();
        }

        public GonzalesClaimItem(string InternalID)
            : base(InternalID)
        {

        }
    }

    public class GonzalesClaimItemWithWeeklyLimit : GonzalesClaimItem, IElement
    {
        public int WeekInYear = 0;
        public decimal TotalSpentInWeek = 0;

        public GonzalesClaimItemWithWeeklyLimit(string InternalID)
            : base(InternalID)
        {

        }
    }

    #region ClaimTypeLimitPolicy
    public class ClaimTypeLimitPolicy
    {
        public string ClaimDetalID = "";
        public string ClaimTypeInternalID = "";
        public string UserInternalID = "";
        public Currency LimitCurrency = null;
        public Currency LocalCurrency = null;
        public decimal LimitAmount = 0;
        public TypeOfClaimLimitDuration Duration = TypeOfClaimLimitDuration.NoLimit;
        public bool Strict = false;
        public decimal ExRateFigure = 0;
        public decimal TotalClaimedInPeriod = 0;        
    }

    public class ClaimTypeLimitPolicies : CollectionBase
    {

        public ClaimTypeLimitPolicy this[int index]
        {
            get
            {
                return ((ClaimTypeLimitPolicy)List[index]);
            }
            set
            {
                List[index] = value;
            }
        }

        public int Add(ClaimTypeLimitPolicy value)
        {
            return (List.Add(value));
        }

        public int IndexOf(ClaimTypeLimitPolicy value)
        {
            return (List.IndexOf(value));
        }

        public void Insert(int index, ClaimTypeLimitPolicy value)
        {
            List.Insert(index, value);
        }

        public void Remove(ClaimTypeLimitPolicy value)
        {
            List.Remove(value);
        }

        public bool Contains(ClaimTypeLimitPolicy value)
        {
            // If value is not of type Int16, this will return false.
            return (List.Contains(value));
        }
    }
    #endregion

    #region WeeklyTotalSpentPolicy
    [Serializable]
    public class WeeklyTotalSpentPolicy
    {
        public int WeekInYear = 0;
        public decimal TotalSpentInWeek = 0;

        public WeeklyTotalSpentPolicy(int WeekInYear, decimal TotalSpentInWeek)
        {
            this.WeekInYear = WeekInYear;
            this.TotalSpentInWeek = TotalSpentInWeek;
        }
    }

    [Serializable]
    public class WeeklyTotalSpentPolicies : CollectionBase
    {

        public WeeklyTotalSpentPolicy this[int index]
        {
            get
            {
                return ((WeeklyTotalSpentPolicy)List[index]);
            }
            set
            {
                List[index] = value;
            }
        }

        public int Add(WeeklyTotalSpentPolicy value)
        {
            return (List.Add(value));
        }

        public int IndexOf(WeeklyTotalSpentPolicy value)
        {
            return (List.IndexOf(value));
        }

        public void Insert(int index, WeeklyTotalSpentPolicy value)
        {
            List.Insert(index, value);
        }

        public void Remove(WeeklyTotalSpentPolicy value)
        {
            List.Remove(value);
        }

        public bool Contains(WeeklyTotalSpentPolicy value)
        {
            // If value is not of type Int16, this will return false.
            return (List.Contains(value));
        }
    }
    #endregion

    #region FinanceApproverRemark

    public class FinanceApproverRemark : ElementBase
    {
        public DateTime CreatedDateTime = DateTime.MinValue;
        public SystemUser CreatedBy = null;
        public SystemUser SendTo = null;
        public int Level = 0;
        public string Content = "";

        public FinanceApproverRemark(string InternalID)
            : base(InternalID)
        {
        }
    }

    public class FinanceApproverRemarks : CollectionBase
    {

        public FinanceApproverRemark this[int index]
        {
            get
            {
                return ((FinanceApproverRemark)List[index]);
            }
            set
            {
                List[index] = value;
            }
        }

        public int Add(FinanceApproverRemark value)
        {
            return (List.Add(value));
        }

        public int IndexOf(FinanceApproverRemark value)
        {
            return (List.IndexOf(value));
        }

        public void Insert(int index, FinanceApproverRemark value)
        {
            List.Insert(index, value);
        }

        public void Remove(FinanceApproverRemark value)
        {
            List.Remove(value);
        }

        public bool Contains(FinanceApproverRemark value)
        {
            // If value is not of type Int16, this will return false.
            return (List.Contains(value));
        }
    }

    #endregion

    #region EntertainmentHeader

    public class EntertainmentHeader : ElementBase
    {
        public string Purpose = "";
        public bool GovOfficial = false;
        public decimal TotalCost = 0;
        public EntertainmentDetails Details = new EntertainmentDetails();

        public EntertainmentHeader(string InternalID)
            : base(InternalID)
        {
        }
    }

    public class EntertainmentDetail : ElementBase
    {
        public string Attendess = null;
        public string Title = null;
        public string Company = null;
        public int Order = 0;
        public decimal CostPerHead = 0;

        public EntertainmentDetail(string InternalID)
            : base(InternalID)
        {
        }
    }

    public class EntertainmentDetails : CollectionBase
    {

        public EntertainmentDetail this[int index]
        {
            get
            {
                return ((EntertainmentDetail)List[index]);
            }
            set
            {
                List[index] = value;
            }
        }

        public int Add(EntertainmentDetail value)
        {
            return (List.Add(value));
        }

        public int IndexOf(EntertainmentDetail value)
        {
            return (List.IndexOf(value));
        }

        public void Insert(int index, EntertainmentDetail value)
        {
            List.Insert(index, value);
        }

        public void Remove(EntertainmentDetail value)
        {
            List.Remove(value);
        }

        public bool Contains(EntertainmentDetail value)
        {
            // If value is not of type Int16, this will return false.
            return (List.Contains(value));
        }
    }

    #endregion

    #region ClaimRefference

    public class ClaimReffrence : ElementBase
    {
        public string Page = "";

        public string DisplayName
        {
            get
            {
                return this.display_name;
            }
        }

        public ClaimReffrence(string InternalID)
            : base(InternalID)
        {
        }

        public ClaimReffrence(string InternalID, string Name)
            : base(InternalID)
        {
            base.display_name = Name;
        }

        public string GenerateLink(string[] Parameters)
        {
            string ResultLink = this.Page;

            if (Parameters != null && Parameters.Length > 0)
            {
                for (int x = 0; x < Parameters.Length; x++)
                {
                    ResultLink = ResultLink.Replace("{" + x + "}", Parameters[x]);
                }
            }

            return ResultLink;
        }
    }
    #endregion
}
